package com.sun.lock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 读写锁
 * 如果有一个线程已经占用了读锁，则此时其他线程如果要申请写锁，则申请写锁的线程会一直等待释放读锁。
 * 如果有一个线程已经占用了写锁，则此时其他线程如果申请写锁或者读锁，则申请的线程也会一直等待释放写锁。
 * @author SunAFei
 * @time 2018年3月14日 上午10:28:47
 * 
 */
public class ReentrantReadWriteLockDemo2 {
	private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

	public static void main(String[] args) {
		final ReentrantReadWriteLockDemo2 test = new ReentrantReadWriteLockDemo2();
		new Thread("O") {
			public void run() {
				test.write(Thread.currentThread());
			};
		}.start();
		new Thread("A") {
			public void run() {
				test.read(Thread.currentThread());
			};
		}.start();

		new Thread("B") {
			public void run() {
				test.read(Thread.currentThread());
			};
		}.start();

		new Thread("C") {
			public void run() {
				test.write(Thread.currentThread());
			};
		}.start();
		new Thread("D") {
			public void run() {
				test.read(Thread.currentThread());
			};
		}.start();
	}

	public void read(Thread thread) {
		rwl.readLock().lock(); // 在外面获取锁
		try {
			System.out.println("线程" + thread.getName() + "开始读操作...");
			System.out.println("线程" + thread.getName() + "正在进行读操作...");
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("线程" + thread.getName() + "读操作完毕...");
		} finally {
			rwl.readLock().unlock();
		}
	}

	public void write(Thread thread) {
		rwl.writeLock().lock(); // 在外面获取锁
		try {
			System.out.println("线程" + thread.getName() + "开始写操作...");
			System.out.println("线程" + thread.getName() + "正在进行写操作...");
			try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("线程" + thread.getName() + "写操作完毕...");
		} finally {
			rwl.writeLock().unlock();
		}
	}
}
